﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace JoyxyAnalyzer.Utils
{
    public class FileHelper
    {
        #region Methods

        /// <summary>
        /// Returns true if the specified file existed
        /// </summary>
        /// <param name="file">the file path</param>
        /// <returns>true if file existed; false otherwise</returns>
        public static bool isFileExisted(string file)
        {
            return System.IO.File.Exists(file);
        }

        /// <summary>
        /// Returns true if the specified direcotry existed
        /// </summary>
        /// <param name="dir">the directory path</param>
        /// <returns>true if directory existed; false otherwise</returns>
        public static bool isDirectoryExisted(string dir)
        {
            return Directory.Exists(dir);
        }

        /// <summary>
        /// Returns the file content from the specified file
        /// </summary>
        /// <param name="file">the file path</param>
        /// <returns>the file content</returns>
        public static string getFileContent(string file)
        {
            if (isFileExisted(file))
            {
                StreamReader streamReader = new StreamReader(file);

                try
                {
                    string line = string.Empty;
                    StringBuilder builder = new StringBuilder();
                    while ((line = streamReader.ReadLine()) != null)
                    {
                        builder.AppendLine(line);
                    }
                    return builder.ToString();
                }
                catch (IOException ex)
                {
                    // TODO
                }
                finally
                {
                    streamReader.Close();
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// Writes the file content into the specified file
        /// </summary>
        /// <param name="saveFile">the destination file</param>
        /// <param name="fileContent">the file content</param>
        /// <returns>the written file</returns>
        public static bool writeFile(string saveFile, string fileContent)
        {
            string dir = Path.GetDirectoryName(saveFile);
            createDirectory(dir);

            string fileName = escapeIllegalCharactersOnFileName(Path.GetFileName(saveFile));
            if (fileName.Contains("&amp;"))
            {
                fileName = fileName.Replace("&amp;", "and");
            }
            if (fileName.Contains("&"))
            {
                fileName = fileName.Replace("&amp;", "and");
            }

            FileStream fs = new FileStream(dir + "\\" + fileName, FileMode.Create);
            StreamWriter writer = new StreamWriter(fs);

            try
            {
                writer.Write(fileContent);
                writer.Flush();
                return true;
            }
            catch (IOException ex)
            {
                // TODO
            }
            finally
            {
                writer.Close();
                fs.Close();
            }

            return false;
        }

        /// <summary>
        /// Creates file
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static void createFile(string filePath)
        {
            if (!File.Exists(filePath))
            {
                FileStream fos = new FileStream(filePath, FileMode.Create);
                fos.Close();
            }
        }

        /// <summary>
        /// Copies and existed file into a new file.
        /// </summary>
        /// <param name="srcFilePath">the source file</param>
        /// <param name="dstFilePath">the destination file</param>
        /// <returns>true if file copied succeed; false otherwise</returns>
        public static bool copyFile(string srcFilePath, string dstFilePath)
        {
            if (isFileExisted(srcFilePath))
            {
                System.IO.File.Copy(srcFilePath, dstFilePath, true);
            }

            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="srcDirPath"></param>
        /// <param name="dstDirPath"></param>
        /// <returns></returns>
        public static bool copyDirectory(string srcDirPath, string dstDirPath)
        {
            if (!srcDirPath.EndsWith("\\"))
            {
                srcDirPath += "\\";
            }

            if (!dstDirPath.EndsWith("\\"))
            {
                dstDirPath += "\\";
            }

            if (!Directory.Exists(dstDirPath))
            {
                Directory.CreateDirectory(dstDirPath);
            }

            foreach (string file in Directory.GetFiles(srcDirPath))
            {
                System.IO.File.Copy(file, dstDirPath + Path.GetFileName(file), true);
            }

            foreach (string subDir in Directory.GetDirectories(srcDirPath))
            {
                copyDirectory(subDir + "\\", dstDirPath + Path.GetFileName(subDir) + "\\");
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dir"></param>
        public static void removeFiles(string dir)
        {
            removeFiles(dir, false);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="excludes"></param>
        public static void removeFiles(string dir, string[] excludes)
        {
            removeFiles(dir, excludes, false);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        public static void removeFiles(string dir, bool isSubDir)
        {
            removeFiles(dir, null, isSubDir);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="excludes"></param>
        /// <param name="isSubDir"></param>
        public static void removeFiles(string dir, string[] excludes, bool isSubDir)
        {
            if (isDirectoryExisted(dir))
            {
                string[] files = Directory.GetFiles(dir);
                if (files != null && files.Length > 0)
                {
                    foreach (string file in files)
                    {
                        if (!isFileIncluded(file, excludes))
                        {
                            System.IO.File.Delete(file);
                        }
                    }
                }

                foreach (string subDir in Directory.GetDirectories(dir))
                {
                    removeFiles(subDir + "\\", true);
                }

                if (isSubDir)
                {
                    Directory.Delete(dir);
                }

            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="file"></param>
        /// <param name="fileList"></param>
        /// <returns></returns>
        private static bool isFileIncluded(string file, string[] fileList)
        {
            if (fileList == null || fileList.Length == 0)
            {
                return false;
            }

            foreach (string tmp in fileList)
            {
                if (file.ToLower().Contains(file.ToLower()))
                {
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        public static bool createDirectory(string dir)
        {
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string escapeIllegalCharactersOnFileName(string fileName)
        {
            return escapeIllegalCharactersOnFileName(fileName, "");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="replaced"></param>
        /// <returns></returns>
        public static string escapeIllegalCharactersOnFileName(string fileName, string replaced)
        {
            if (fileName != string.Empty)
            {
                if (fileName.Contains("\\"))
                {
                    fileName = fileName.Replace("\\", replaced);
                }

                if (fileName.Contains("/"))
                {
                    fileName = fileName.Replace("/", replaced);
                }

                if (fileName.Contains(":"))
                {
                    fileName = fileName.Replace(":", replaced);
                }

                if (fileName.Contains("*"))
                {
                    fileName = fileName.Replace("*", replaced);
                }

                if (fileName.Contains("%20"))
                {
                    fileName = fileName.Replace("%20", replaced);
                }

                if (fileName.Contains("?"))
                {
                    fileName = fileName.Replace("?", replaced);
                }

                if (fileName.Contains("<"))
                {
                    fileName = fileName.Replace("<", replaced);
                }

                if (fileName.Contains(">"))
                {
                    fileName = fileName.Replace(">", replaced);
                }

                if (fileName.Contains("|"))
                {
                    fileName = fileName.Replace("|", replaced);
                }

            }

            return fileName;
        }

        #endregion Methods
    }
}
